package com.dede.monochromatism.activity

import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.RecyclerView
import android.text.SpannableString
import android.view.*
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import com.dede.applib.extends.getString
import com.dede.applib.extends._3Y
import com.dede.applib.extends.color
import com.dede.applib.extends.size
import com.dede.monochromatism.R
import com.dede.monochromatism.base.BaseActivity
import com.dede.monochromatism.data.AppInfo
import com.dede.monochromatism.db.PackageDb
import com.dede.monochromatism.db.contains
import com.dede.monochromatism.db.database
import com.dede.monochromatism.db.openTable
import com.dede.monochromatism.layout.AppListActivityUI
import com.turingtechnologies.materialscrollbar.DragScrollBar
import com.turingtechnologies.materialscrollbar.INameableAdapter
import org.jetbrains.anko.*
import org.jetbrains.anko.db.insert
import org.jetbrains.anko.sdk25.coroutines.onClick
import java.util.*


/**
 * @author hsh
 * @date 2017/9/19 10:45.
 * @doc
 */
class AppListActivity : BaseActivity() {

    lateinit var recyclerView: RecyclerView
    lateinit var swipeRefresh: SwipeRefreshLayout
    lateinit var scrollBar: DragScrollBar

    private val checkedList = arrayListOf<AppInfo>()

    private val table: String by lazy {
        getString("table", openTable)
    }

    private val isOpenTable by lazy {
        table == openTable
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        showBackButton(true)
        AppListActivityUI().setContentView(this)

        recyclerView.adapter = AppListAdapter(arrayListOf())

        if (isOpenTable) {
            supportActionBar?.title = getString(R.string.auto_list)
            checkedList.addAll(PackageDb.getOpenList())
        } else {
            supportActionBar?.title = getString(R.string.ignore_list)
            checkedList.addAll(PackageDb.getIgnoreList())
        }

        loadAllApp()
    }

    internal fun loadAllApp() {
        swipeRefresh.isRefreshing = true
        doAsync {
            val allAppList = arrayListOf<AppInfo>()
            val manager = packageManager
            manager.getInstalledPackages(0)
                    .filter { showAllApp || it.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) == 0 }//过滤系统应用
                    .forEach {
                        if (isOpenTable) {
                            if (PackageDb.getIgnoreList().contains(it.packageName)) {
                                return@forEach//带标签只是结束此次语句块，继续进行下一次循环
                            }
                        } else {
                            if (PackageDb.getOpenList().contains(it.packageName)) {
                                return@forEach
                            }
                        }
                        val appInfo = AppInfo(it.packageName,
                                it.applicationInfo.loadLabel(manager).toString(),
                                it.applicationInfo.loadIcon(manager))
                        appInfo.isChecked = checkedList.contains(appInfo)
                        appInfo.versionCode = it.versionCode
                        appInfo.versionName = it.versionName
                        allAppList.add(appInfo)
                    }
            Collections.sort(allAppList)
            uiThread {
                swipeRefresh.isRefreshing = false
                (recyclerView.adapter as AppListAdapter).setDate(allAppList)
            }
        }
    }

    private var showAllApp = false//是否显示所有应用

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_all_app -> {
                item.isChecked = !item.isChecked
                showAllApp = item.isChecked
                loadAllApp()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_app_list, menu)
        return true
    }

    fun add(info: AppInfo) {
        checkedList.add(info)
        doAsync({ it.printStackTrace() }) {
            if (table == openTable) {
                PackageDb.addOpenList(info)
            } else {
                PackageDb.addIgnoreList(info)
            }
            database.use {
                insert(table, "name" to info.name,
                        "packageName" to info.packageName)
            }
        }
    }

    fun remove(info: AppInfo) {
        checkedList.remove(info)
        doAsync({ it.printStackTrace() }) {
            if (table == openTable) {
                PackageDb.removeOpenList(info)
            } else {
                PackageDb.removeIgnoreList(info)
            }
            database.use {
                delete(table, "packageName=?",
                        arrayOf(info.packageName))
            }
        }
    }

    inner class AppListAdapter(val data: ArrayList<AppInfo>) : RecyclerView.Adapter<AppListHolder>(), INameableAdapter {

        override fun getCharacterForElement(element: Int): Char {
            val appInfo = data[element]
            _3Y(appInfo.isChecked, {
                scrollBar.setTextColourRes(android.R.color.black)
            }, {
                scrollBar.setTextColourRes(android.R.color.white)
            })
            return appInfo.pinyin[0]
        }

        fun setDate(data: ArrayList<AppInfo>) {
            this.data.clear()
            this.data.addAll(data)
            notifyDataSetChanged()
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppListHolder {
            return AppListHolder(parent.context)
        }

        override fun onBindViewHolder(holder: AppListHolder, position: Int) {
            val appInfo = data[position]
            val versionString = "  ${appInfo.versionName} (${appInfo.versionCode})"
            val appName = appInfo.name
            holder.name.text = SpannableString(appName + versionString)
                    .size(dip(10), appName.length)
                    .color(color(R.color.colorSubText), appName.length)
            holder.packageName.text = appInfo.packageName
            holder.icon.setImageDrawable(appInfo.icon)
            holder.cb.isChecked = appInfo.isChecked

            holder.itemView.onClick {
                holder.cb.isChecked = !holder.cb.isChecked

                val checked = holder.cb.isChecked
                appInfo.isChecked = checked
                if (checked) {
                    add(appInfo)
                } else {
                    remove(appInfo)
                }
            }

            holder.itemView.setOnLongClickListener {
                startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                        Uri.parse("package:${appInfo.packageName}")))
                return@setOnLongClickListener true
            }
        }

        override fun getItemCount(): Int = data.size
    }

    class AppListHolder(view: View) : RecyclerView.ViewHolder(view) {
        companion object {
            val iconId = 10000
            val nameId = 10001
            val packageNameId = 10003
            val cbId = 10002
        }

        val icon = super.itemView.find<ImageView>(iconId)
        val name = super.itemView.find<TextView>(nameId)
        val packageName = super.itemView.find<TextView>(packageNameId)
        val cb = super.itemView.find<CheckBox>(cbId)

        constructor(context: Context) : this(
                context.linearLayout {
                    lparams(matchParent, wrapContent) {
                        horizontalPadding = dip(15)
                        verticalPadding = dip(10)
                        verticalGravity = Gravity.CENTER_VERTICAL
                        backgroundResource = R.drawable.selector_item
                    }

                    imageView {
                        id = iconId
                    }.lparams(dip(35), dip(35))

                    verticalLayout {
                        lparams(0, wrapContent, 1f) {
                            horizontalMargin = dip(10)
                        }
                        textView {
                            id = nameId
                            textSize = 16f
                            textColor = color(R.color.colorText)
                        }
                        textView {
                            id = packageNameId
                            textSize = 12f
                            textColor = color(R.color.colorSubText)
                        }.lparams {
                            topMargin = dip(3)
                        }
                    }

                    checkBox {
                        id = cbId
                        isClickable = false
                        isFocusable = false
                    }.lparams(wrapContent, wrapContent)
                })
    }

}